﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SCMS.Model;
using System.Data.Objects.DataClasses;
using System.Transactions;
using SCMS.CoreBusinessLogic.NotificationsManager;
using SCMS.CoreBusinessLogic._ExchangeRate;

namespace SCMS.CoreBusinessLogic.Request4Advance
{
    public class Request4Advance : IRequest4Advance
    {
        private INotificationService NotificationService;
        private IExchangeRateService exchangeRateService;

        public Request4Advance(INotificationService NotificationService, IExchangeRateService exchangeRateService)
        {
            this.NotificationService = NotificationService;
            this.exchangeRateService = exchangeRateService;
        }

        public string GenerateUniquNumber(CountryProgramme cp)
        {
            string code = "RFA/DRC/" + cp.Country.ShortName + "/";
            string refNumber = "";
            long count = 1;
            using (var dbContext = new SCMSEntities())
            {
                var total = dbContext.AdvanceRequests.Where(p => p.CountryProgrammeId == cp.Id && p.IsSubmitted == true).Count();
                count = total;
                Model.AdvanceRequest m = null;
                do
                {
                    count++;
                    if (count < 10000)
                    {
                        if (count < 10)
                            refNumber = code + "0000" + count;
                        if (count < 100 & count >= 10)
                            refNumber = code + "000" + count;
                        if (count < 1000 & count >= 100)
                            refNumber = code + "00" + count;
                        if (count < 10000 & count >= 1000)
                            refNumber = code + "0" + count;
                    }
                    m = dbContext.AdvanceRequests.FirstOrDefault(p => p.RefNumber == refNumber);
                } while (m != null);
                return refNumber;
            }
        }

        public bool SaveRequest4Advance(Model.AdvanceRequest entity, EntityCollection<AdvanceRequestBudgetLine> collection)
        {
            using (TransactionScope scope = new TransactionScope())
            {
                using (var context = new SCMSEntities())
                {
                    try
                    {
                        context.AdvanceRequests.AddObject(entity);
                        //if (context.SaveChanges() > 0)
                       // {
                            foreach (AdvanceRequestBudgetLine item in collection)
                            {
                                context.AdvanceRequestBudgetLines.AddObject(item);
                                if (!(context.SaveChanges() > 0)) { scope.Dispose(); return false; }
                            }                            
                            scope.Complete();
                            return true;
                        //}
                       // else { scope.Dispose(); return false; }
                    }
                    catch (Exception ex) { scope.Dispose(); throw new Exception(ex.Message); }

                }
            }

        }

        public List<Model.AdvanceRequest> GetAdvanceRequests(Guid cpId)
        {
            using (var context = new SCMSEntities())
            {
                List<Model.AdvanceRequest> AR = context.AdvanceRequests.Where(a => a.CountryProgrammeId == cpId).OrderByDescending(p => p.PreparedOn).ToList();
                foreach (AdvanceRequest item in AR)
                {
                    Currency c = item.Currency;
                    Currency cc = item.Currency1;
                    PaymentType pt = item.PaymentType;
                    PaymentTerm pterm = item.PaymentTerm;
                    if (item.Staff != null)
                    {
                        var person = item.Staff.Person;
                        var desg = item.Staff.Designation;
                    }                    
                    if (item.Staff1 != null)
                    {
                        var person = item.Staff1.Person;
                        var desg = item.Staff1.Designation;
                    }
                    if (item.Staff2 != null)
                    {
                        var person = item.Staff2.Person;
                        var desg = item.Staff2.Designation;
                    }
                    if (item.Staff3 != null)
                    {
                        var person = item.Staff3.Person;
                        var desg = item.Staff3.Designation;
                    }
                    if (item.Staff4 != null)
                    {
                        var person = item.Staff4.Person;
                        var desg = item.Staff4.Designation;
                    }
                }
                return AR;
            }
        }

        public bool SaveRFA(AdvanceRequest rfa)
        {
            using (var context = SCMSEntities.Define())
            {
                var advance = context.AdvanceRequests.FirstOrDefault(a => a.Id == rfa.Id);
                if (advance == null)
                    context.AdvanceRequests.AddObject(rfa);
                else
                {
                    if (rfa.EntityKey == null)
                        rfa.EntityKey = advance.EntityKey;
                    context.Detach(advance);
                    context.AdvanceRequests.Attach(rfa);
                    context.ObjectStateManager.ChangeObjectState(rfa, System.Data.EntityState.Modified);
                }
                return context.SaveChanges() > 0 ? true : false;
            }
        }

        public bool SaveRFADetail(AdvanceRequestBudgetLine rfaBL)
        {
            using (var context = SCMSEntities.Define())
            {
                var advance = context.AdvanceRequestBudgetLines.FirstOrDefault(a => a.Id == rfaBL.Id);
                if (advance == null)
                    context.AdvanceRequestBudgetLines.AddObject(rfaBL);
                else
                {
                    if (rfaBL.EntityKey == null)
                        rfaBL.EntityKey = advance.EntityKey;
                    context.Detach(advance);
                    context.AdvanceRequestBudgetLines.Attach(rfaBL);
                    context.ObjectStateManager.ChangeObjectState(rfaBL, System.Data.EntityState.Modified);
                }   
                //Update RFA Total Amount
                UpdateRFATotalAmount(context, rfaBL);
                return context.SaveChanges() > 0 ? true : false;
            }
        }

        public AdvanceRequest GetRFAById(Guid Id)
        {
            using (var context = SCMSEntities.Define())
            {
                var rfa = context.AdvanceRequests.SingleOrDefault(a => a.Id == Id);
                Currency c = rfa.Currency;
                Currency cc = rfa.Currency1;
                PaymentType pt = rfa.PaymentType;
                PaymentTerm pterm = rfa.PaymentTerm;
                if (rfa.Staff != null)
                {
                    var person = rfa.Staff.Person;
                    var desg = rfa.Staff.Designation;
                }
                if (rfa.Staff1 != null)
                {
                    var person = rfa.Staff1.Person;
                    var desg = rfa.Staff1.Designation;
                }
                if (rfa.Staff2 != null)
                {
                    var person = rfa.Staff2.Person;
                    var desg = rfa.Staff2.Designation;
                }
                if (rfa.Staff3 != null)
                {
                    var person = rfa.Staff3.Person;
                    var desg = rfa.Staff3.Designation;
                }
                if (rfa.Staff4 != null)
                {
                    var person = rfa.Staff4.Person;
                    var desg = rfa.Staff4.Designation;
                }
                return rfa;
            }
        }

        public List<AdvanceRequestBudgetLine> GetRFADetails(Guid rfaId)
        {
            using (var context = SCMSEntities.Define())
            {
                var rfaBLList = context.AdvanceRequestBudgetLines.Where(a => a.AdvanceRequestId == rfaId).ToList();
                foreach (var rfaBL in rfaBLList)
                {
                    var pd = rfaBL.ProjectBudget.BudgetCategory.ProjectDonor;
                    var option = rfaBL.AdvanceRequestOption;
                }
                return rfaBLList;
            }
        }

        public AdvanceRequestBudgetLine GetRFABLById(Guid Id)
        {
            using (var context = SCMSEntities.Define())
            {
                var rfaBL = context.AdvanceRequestBudgetLines.SingleOrDefault(a => a.Id == Id);
                var rfa = rfaBL.AdvanceRequest;
                var option = rfaBL.AdvanceRequestOption;
                var pd = rfaBL.ProjectBudget.BudgetCategory.ProjectDonor;
                return rfaBL;
            }
        }

        public bool DeleteRFA(Guid Id)
        {
            using (var context = new SCMSEntities())
            {
                var rfa = context.AdvanceRequests.SingleOrDefault(a => a.Id == Id);
                context.AdvanceRequests.DeleteObject(rfa);
                return context.SaveChanges() > 0 ? true : false;
            }
        }

        public bool DeleteRFADetail(Guid Id)
        {
            using (var context = new SCMSEntities())
            {
                var rfaBL = context.AdvanceRequestBudgetLines.SingleOrDefault(a => a.Id == Id);
                context.AdvanceRequestBudgetLines.DeleteObject(rfaBL);

                //Update RFA Total Amount
                UpdateRFATotalAmount(context, rfaBL);
                return context.SaveChanges() > 0 ? true : false;
            }
        }

        private static void UpdateRFATotalAmount(SCMSEntities context, AdvanceRequestBudgetLine rfaBL)
        {
            var rfa = context.AdvanceRequests.FirstOrDefault(a => a.Id == rfaBL.AdvanceRequestId);
            rfa.TotalAdvance = 0;
            foreach (var bl in rfa.AdvanceRequestBudgetLines)
            {
                rfa.TotalAdvance += bl.Amount;
            }
        }

        public List<AdvanceRequestOption> GetAdvanceOptions()
        {
            using (var context = new SCMSEntities())
            {
                return context.AdvanceRequestOptions.ToList();
            }
        }

        public List<AdvanceRequest> GetAdvanceRequestsForReview(SystemUser currentUser)
        {
            try
            {
                using (var context = new SCMSEntities())
                {
                    List<Model.AdvanceRequest> requestsForAdvance = new List<Model.AdvanceRequest>();
                    context.SystemUsers.Attach(currentUser);
                    var approvers = context.Approvers.Where(a => a.UserId == currentUser.Id && a.ActivityCode == NotificationHelper.rfaCode && a.ActionType == NotificationHelper.reviewCode).ToList();
                    var delegateApprovers = context.Approvers.Where(a => a.AssistantId == currentUser.Id && a.ActivityCode == NotificationHelper.rfaCode && a.ActionType == NotificationHelper.reviewCode).ToList();
                    if (approvers != null)
                    {
                        foreach (var approver in approvers)
                        {
                            var rfaList = context.AdvanceRequests.Where(r => r.CountryProgrammeId == currentUser.Staff.CountrySubOffice.CountryProgrammeId && (r.IsSubmitted == true && r.IsReviewed == false && r.IsRejected == false)
                                && r.Notifications.Where(n => (Guid)n.AdvanceRequestId == r.Id && n.IsRespondedTo == false && n.SentToDelegate == false && n.ApproverId == approver.Id).Count() > 0).ToList();
                            foreach (var rfa in rfaList)
                            {
                                Currency c = rfa.Currency;
                                PaymentType pt = rfa.PaymentType;
                                PaymentTerm pterm = rfa.PaymentTerm;
                                if (rfa.Staff != null)
                                {
                                    var person = rfa.Staff.Person;
                                    var desg = rfa.Staff.Designation;
                                }
                                if (rfa.Staff1 != null)
                                {
                                    var person = rfa.Staff1.Person;
                                    var desg = rfa.Staff1.Designation;
                                }
                                if (rfa.Staff2 != null)
                                {
                                    var person = rfa.Staff2.Person;
                                    var desg = rfa.Staff2.Designation;
                                }
                                if (rfa.Staff3 != null)
                                {
                                    var person = rfa.Staff3.Person;
                                    var desg = rfa.Staff3.Designation;
                                }
                                if (rfa.Staff4 != null)
                                {
                                    var person = rfa.Staff4.Person;
                                    var desg = rfa.Staff4.Designation;
                                }
                                requestsForAdvance.Add(rfa);
                            }
                        }
                    }
                    if (delegateApprovers != null)
                    {
                        foreach (var delegateApprover in delegateApprovers)
                        {
                            var rfaList = context.AdvanceRequests.Where(r => r.CountryProgrammeId == currentUser.Staff.CountrySubOffice.CountryProgrammeId && (r.IsSubmitted == true && r.IsReviewed == false && r.IsRejected == false)
                                && r.Notifications.Where(n => (Guid)n.AdvanceRequestId == r.Id && n.IsRespondedTo == false && n.SentToDelegate == true && n.ApproverId == delegateApprover.Id).Count() > 0).ToList();
                            foreach (var rfa in rfaList)
                            {
                                Currency c = rfa.Currency;
                                PaymentType pt = rfa.PaymentType;
                                PaymentTerm pterm = rfa.PaymentTerm;
                                if (rfa.Staff != null)
                                {
                                    var person = rfa.Staff.Person;
                                    var desg = rfa.Staff.Designation;
                                }
                                if (rfa.Staff1 != null)
                                {
                                    var person = rfa.Staff1.Person;
                                    var desg = rfa.Staff1.Designation;
                                }
                                if (rfa.Staff2 != null)
                                {
                                    var person = rfa.Staff2.Person;
                                    var desg = rfa.Staff2.Designation;
                                }
                                if (rfa.Staff3 != null)
                                {
                                    var person = rfa.Staff3.Person;
                                    var desg = rfa.Staff3.Designation;
                                }
                                if (rfa.Staff4 != null)
                                {
                                    var person = rfa.Staff4.Person;
                                    var desg = rfa.Staff4.Designation;
                                }
                                requestsForAdvance.Add(rfa);
                            }
                        }
                    }
                    return requestsForAdvance;
                }
            }
            catch (Exception ex)
            {
                return new List<Model.AdvanceRequest>();
            }
        }

        public List<AdvanceRequest> GetAdvanceRequestsForAuth(SystemUser currentUser)
        {
            try
            {
                using (var context = new SCMSEntities())
                {
                    List<Model.AdvanceRequest> requestsForAdvance = new List<Model.AdvanceRequest>();
                    context.SystemUsers.Attach(currentUser);
                    var approvers = context.Approvers.Where(a => a.UserId == currentUser.Id && a.ActivityCode == NotificationHelper.rfaCode && a.ActionType == NotificationHelper.authorizationCode).ToList();
                    var delegateApprovers = context.Approvers.Where(a => a.AssistantId == currentUser.Id && a.ActivityCode == NotificationHelper.rfaCode && a.ActionType == NotificationHelper.authorizationCode).ToList();
                    if (approvers != null)
                    {
                        foreach (var approver in approvers)
                        {
                            var rfaList = context.AdvanceRequests.Where(r => r.CountryProgrammeId == currentUser.Staff.CountrySubOffice.CountryProgrammeId && (r.IsReviewed == true && r.IsRejected == false && r.IsAuthorized != null && r.IsAuthorized == false)
                                && r.Notifications.Where(n => (Guid)n.AdvanceRequestId == r.Id && n.IsRespondedTo == false && n.SentToDelegate == false && n.ApproverId == approver.Id).Count() > 0).ToList();
                            foreach (var rfa in rfaList)
                            {
                                Currency c = rfa.Currency;
                                PaymentType pt = rfa.PaymentType;
                                PaymentTerm pterm = rfa.PaymentTerm;
                                if (rfa.Staff != null)
                                {
                                    var person = rfa.Staff.Person;
                                    var desg = rfa.Staff.Designation;
                                }
                                if (rfa.Staff1 != null)
                                {
                                    var person = rfa.Staff1.Person;
                                    var desg = rfa.Staff1.Designation;
                                }
                                if (rfa.Staff2 != null)
                                {
                                    var person = rfa.Staff2.Person;
                                    var desg = rfa.Staff2.Designation;
                                }
                                if (rfa.Staff3 != null)
                                {
                                    var person = rfa.Staff3.Person;
                                    var desg = rfa.Staff3.Designation;
                                }
                                if (rfa.Staff4 != null)
                                {
                                    var person = rfa.Staff4.Person;
                                    var desg = rfa.Staff4.Designation;
                                }
                                requestsForAdvance.Add(rfa);
                            }
                        }
                    }
                    if (delegateApprovers != null)
                    {
                        foreach (var delegateApprover in delegateApprovers)
                        {
                            var rfaList = context.AdvanceRequests.Where(r => r.CountryProgrammeId == currentUser.Staff.CountrySubOffice.CountryProgrammeId && (r.IsReviewed == true && r.IsRejected == false && r.IsAuthorized != null && r.IsAuthorized == false)
                                && r.Notifications.Where(n => (Guid)n.AdvanceRequestId == r.Id && n.IsRespondedTo == false && n.SentToDelegate == true && n.ApproverId == delegateApprover.Id).Count() > 0).ToList();
                            foreach (var rfa in rfaList)
                            {
                                Currency c = rfa.Currency;
                                PaymentType pt = rfa.PaymentType;
                                PaymentTerm pterm = rfa.PaymentTerm;
                                if (rfa.Staff != null)
                                {
                                    var person = rfa.Staff.Person;
                                    var desg = rfa.Staff.Designation;
                                }
                                if (rfa.Staff1 != null)
                                {
                                    var person = rfa.Staff1.Person;
                                    var desg = rfa.Staff1.Designation;
                                }
                                if (rfa.Staff2 != null)
                                {
                                    var person = rfa.Staff2.Person;
                                    var desg = rfa.Staff2.Designation;
                                }
                                if (rfa.Staff3 != null)
                                {
                                    var person = rfa.Staff3.Person;
                                    var desg = rfa.Staff3.Designation;
                                }
                                if (rfa.Staff4 != null)
                                {
                                    var person = rfa.Staff4.Person;
                                    var desg = rfa.Staff4.Designation;
                                }
                                requestsForAdvance.Add(rfa);
                            }
                        }
                    }
                    return requestsForAdvance;
                }
            }
            catch (Exception ex)
            {
                return new List<Model.AdvanceRequest>();
            }
        }

        public List<AdvanceRequest> GetAdvanceRequestsForPosting(Guid countryProgId, SystemUser currentUser)
        {
            using (var context = new SCMSEntities())
            {
                List<AdvanceRequest> advanceRequests = new List<AdvanceRequest>();
                var approvers = context.Approvers.Where(a => a.CountryProgrammeId == countryProgId && a.ActivityCode == NotificationHelper.rfaCode && a.ActionType == NotificationHelper.postFundsCode
                    && (a.UserId == currentUser.Id || a.AssistantId == currentUser.Id));
                var financeLimit = context.SystemUsers.FirstOrDefault(s => s.Id == currentUser.Id).Staff.FinanceLimit;
                if (financeLimit == null)
                    return new List<AdvanceRequest>();
                if (approvers.ToList().Count == 0)
                    return new List<AdvanceRequest>();
                if (approvers.Where(a => a.ProjectDonorId == null).Count() > 0)
                {
                    advanceRequests = context.AdvanceRequests.Where(a => a.CountryProgrammeId == countryProgId && a.IsAuthorized == true && a.FundsPosted == false
                        && (a.MBTotal.Value <= financeLimit.Limit || financeLimit.Limit == 0)).ToList();
                    foreach (var rfa in advanceRequests)
                    {
                        Currency c = rfa.Currency;
                        Currency cc = rfa.Currency1;
                        PaymentType pt = rfa.PaymentType;
                        PaymentTerm pterm = rfa.PaymentTerm;
                        if (rfa.Staff != null)
                        {
                            var person = rfa.Staff.Person;
                            var desg = rfa.Staff.Designation;
                        }
                        if (rfa.Staff1 != null)
                        {
                            var person = rfa.Staff1.Person;
                            var desg = rfa.Staff1.Designation;
                        }
                        if (rfa.Staff2 != null)
                        {
                            var person = rfa.Staff2.Person;
                            var desg = rfa.Staff2.Designation;
                        }
                        if (rfa.Staff3 != null)
                        {
                            var person = rfa.Staff3.Person;
                            var desg = rfa.Staff3.Designation;
                        }
                        if (rfa.Staff4 != null)
                        {
                            var person = rfa.Staff4.Person;
                            var desg = rfa.Staff4.Designation;
                        }
                    }
                    return advanceRequests;
                }

                foreach (var approver in approvers.ToList())
                {
                    var rfas = context.AdvanceRequests.Where(a => a.CountryProgrammeId == countryProgId && a.IsAuthorized == true && a.FundsPosted == false
                        && (a.MBTotal.Value <= financeLimit.Limit || financeLimit.Limit == 0)
                        && a.AdvanceRequestBudgetLines.Where(i => i.ProjectBudget.BudgetCategory.ProjectDonorId.Value == approver.ProjectDonorId.Value).Count() > 0).ToList();
                    foreach (var rfa in rfas)
                    {
                        if (!RfaExistsInList(rfa, advanceRequests))
                        {
                            Currency c = rfa.Currency;
                            PaymentType pt = rfa.PaymentType;
                            PaymentTerm pterm = rfa.PaymentTerm;
                            if (rfa.Staff != null)
                            {
                                var person = rfa.Staff.Person;
                                var desg = rfa.Staff.Designation;
                            }
                            if (rfa.Staff1 != null)
                            {
                                var person = rfa.Staff1.Person;
                                var desg = rfa.Staff1.Designation;
                            }
                            if (rfa.Staff2 != null)
                            {
                                var person = rfa.Staff2.Person;
                                var desg = rfa.Staff2.Designation;
                            }
                            if (rfa.Staff3 != null)
                            {
                                var person = rfa.Staff3.Person;
                                var desg = rfa.Staff3.Designation;
                            }
                            if (rfa.Staff4 != null)
                            {
                                var person = rfa.Staff4.Person;
                                var desg = rfa.Staff4.Designation;
                            }
                            advanceRequests.Add(rfa);
                        }
                    }
                }
                return advanceRequests;
            }
        }

        private bool RfaExistsInList(AdvanceRequest rfa, List<AdvanceRequest> rfaList)
        {
            foreach (var e in rfaList)
            {
                if (e.Equals(rfa))
                    return true;
            }
            return false;
        }

        public bool CommitFunds(AdvanceRequest rfa)
        {
            decimal commitAmount = 0;
            using(var context = SCMSEntities.Define())
            {
                using(TransactionScope scope = new TransactionScope())
                {
                    try
                    {
                        var rfaDetails = context.AdvanceRequestBudgetLines.Where(a => a.AdvanceRequestId == rfa.Id).ToList();
                        foreach (var rfaBL in rfaDetails)
                        {
                            commitAmount = (decimal)exchangeRateService.GetForeignCurrencyValue(rfaBL.ProjectBudget.BudgetCategory.ProjectDonor.Currency, rfaBL.AdvanceRequest.Currency, rfaBL.Amount, rfaBL.AdvanceRequest.CountryProgramme.Id);
                            var bc = new BudgetCommitment();
                            bc.Id = Guid.NewGuid();
                            bc.AmountCommitted = commitAmount;
                            bc.BudgetLineId = rfaBL.BudgetLineId;
                            bc.DateCommitted = DateTime.Now;
                            bc.RFABudgetLineId = rfaBL.Id;
                            context.BudgetCommitments.AddObject(bc);
                            rfaBL.ProjectBudget.TotalCommitted += commitAmount;
                        }
                        if (context.SaveChanges() > 0)
                        {
                            scope.Complete();
                            return true;
                        }
                        else
                        {
                            scope.Dispose();
                            return false;
                        }
                    }
                    catch (Exception ex)
                    {
                        scope.Dispose();
                        throw ex;
                    }
                }
            }
        }

        public bool EffectPosting(AdvanceRequest rfa, Staff poster)
        {
            using (var context = SCMSEntities.Define())
            {
                using (TransactionScope scope = new TransactionScope())
                {
                    try
                    {
                        var rfaCommits = context.BudgetCommitments.Where(b => b.AdvanceRequestBudgetLine.AdvanceRequestId == rfa.Id).ToList();
                        foreach (var rfaCommit in rfaCommits)
                        {
                            var pb = rfaCommit.ProjectBudget;
                            pb.TotalCommitted -= rfaCommit.AmountCommitted;

                            var bp = new BudgetPosting();
                            bp.Id = Guid.NewGuid();
                            bp.AmountPosted = rfaCommit.AmountCommitted;
                            bp.DatePosted = DateTime.Now;
                            bp.PostedBy = poster.Id;
                            bp.RFABudgetLineId = rfaCommit.RFABudgetLineId;
                            pb.TotalPosted += bp.AmountPosted;

                            //Delete commitment and add posting
                            context.BudgetCommitments.DeleteObject(rfaCommit);
                            context.BudgetPostings.AddObject(bp);
                        }

                        var advanceRequest = context.AdvanceRequests.FirstOrDefault(a => a.Id == rfa.Id);
                        advanceRequest.FundsPosted = true;
                        advanceRequest.PostedBy = poster.Id;
                        advanceRequest.PostedOn = DateTime.Now;

                        if (context.SaveChanges() > 0)
                        {
                            scope.Complete();
                            return true;
                        }
                        else
                        {
                            scope.Dispose();
                            return false;
                        }
                    }
                    catch (Exception ex)
                    {
                        scope.Dispose();
                        throw ex;
                    }
                }
            }
        }

        /// <summary>
        /// Send notification to requestor and project managers of the affected budget lines
        /// </summary>
        /// <param name="rfa"></param>
        public void NotifyAffected(AdvanceRequest rfa)
        {
            using (var context = new SCMSEntities())
            {
                //Get ProjectBLCount list order by highest budget line count to least for this RFA
                List<ProjectBLCount> projects = context.AdvanceRequestBudgetLines.Where(a => a.AdvanceRequestId == rfa.Id).GroupBy(bl => bl.ProjectBudget.BudgetCategory.ProjectDonor).
                    Select(projList => new ProjectBLCount
                    {
                        ProjectDonorId = projList.FirstOrDefault().ProjectBudget.BudgetCategory.ProjectDonor.Id,
                        BudgetLineCount = projList.Count()
                    }).OrderByDescending(p => p.BudgetLineCount).ToList<ProjectBLCount>();
                //Notify requestor
                var requestor = context.Staffs.FirstOrDefault(s => s.Id == rfa.PreparedBy).Person;
                var msgBody = string.Format(NotificationHelper.rfaFundsPostedMsgBody, requestor.FirstName, rfa.RefNumber);
                NotificationService.SendNotification(requestor.OfficialEmail, msgBody, NotificationHelper.rfasubject);

                //Notify the Project Manager(s)
                foreach (var project in projects)
                {
                    var proj = context.ProjectDonors.FirstOrDefault(p => p.Id == project.ProjectDonorId);
                    var name = proj.Staff.Person.FirstName;
                    var email = proj.Staff.Person.OfficialEmail;
                    msgBody = string.Format(NotificationHelper.rfaPMNotifyFundsPostedMsgBody, name, rfa.RefNumber, proj.ProjectNumber);
                    NotificationService.SendNotification(email, msgBody, NotificationHelper.rfasubject);
                }
            }
        }
    }
}
